/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package libraries;

import GUI.JFrameBase;
import controller.Controller;
import controller.Controller.ControllerAddListener;
import controller.Controller.ControllerListener;
import controller.Controller.ControllerUpdateListener;
import java.awt.Dimension;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.table.DefaultTableModel;
import javax.swing.tree.DefaultTreeModel;
import model.Consultation;
import model.DB2Hash;
import view.AcquisitionPanelView;
import view.PatientPanelView;
import view.PatientTreeView;
import view.StudyPanelView;
import view.WorklistPanelView;
import view.ReferralNotePanelView;
import view.WorklistTreeView;

/**
 *
 * @author aeguzkiza
 */
public class Application {
    JFrameBase frame;
    Controller controller;
    //DateFormat df = new SimpleDateFormat("yyyy/MM/dd");
    static DateFormat tf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
    public Dimension screenSize;
    
    private static Application AP = new Application();
    public static Application getInstance() {
        return AP;
    }

    /**
    * @param args the command line arguments
    */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                getInstance().initInterface();                
            }
        });
    }
    
    public void initInterface() {
            System.out.println("========== Start of updateTreeValues ==========");
            final Consultation consultation = new Consultation();
            this.frame = new JFrameBase();
                        
            final PatientTreeView patientTreeView = new PatientTreeView(frame);
            final WorklistTreeView worklistTreeView = new WorklistTreeView(frame);
            final WorklistPanelView worklistPanelView = new WorklistPanelView(frame);
            final ReferralNotePanelView referralNotePanelView = new ReferralNotePanelView(frame);
            final PatientPanelView patientPanelView = new PatientPanelView(frame);
            final AcquisitionPanelView acquisitionPanelView = new AcquisitionPanelView(frame);
            final StudyPanelView studyPanelView = new StudyPanelView(frame);
            this.controller = new Controller();
            
            frame.setApplication(this);
            frame.setConsultation(consultation);
            frame.setPatientTreeView(patientTreeView);
            frame.setWorklistTreeView(worklistTreeView);
            frame.setController(controller);

            System.out.println("========== End of updateTreeValues ==========");
            // On initialization is not necessary to go through the controller.
            controller.registerUpdateListener(new ControllerUpdateListener() {

                public void updatePatientList(DB2Hash patient) {
                    patientTreeView.updateViewAddPatient(Integer.parseInt(patient.get("Id")), patient.get("PatientsName"), patient.get("PatientsSurName"));
                    worklistTreeView.updateViewAddPatient(Integer.parseInt(patient.get("Id")), patient.get("PatientsName"), patient.get("PatientsSurName"));
                }

                public void updateStudyList(DB2Hash study, DB2Hash worklist) {
                    // DefaultMutableTreeNode parentNode here is always null: values for this parameter are defined in TreeView.                    
                    patientTreeView.updateViewAddStudy(null, Integer.parseInt(study.get("Id")), study.get("StudyDate"), worklist.get("Id"), Integer.parseInt(study.get("Revised")));
                    worklistTreeView.updateViewAddStudy(null, Integer.parseInt(study.get("Id")), worklist.get("ScheduledProcedureStepDate"), Integer.parseInt(study.get("Revised")));
                }

                public void updateAcquisitionList(DB2Hash acquisition, Integer revised) {
                    patientTreeView.updateViewAddAcquisition(null, Integer.parseInt(acquisition.get("Id")), acquisition.get("ImageLaterality"), acquisition.get("AcquisitionTime"), revised);
                    worklistTreeView.updateViewAddAcquisition(null, Integer.parseInt(acquisition.get("Id")), acquisition.get("AcquisitionTime"), acquisition.get("AcquisitionName"), acquisition.get("ImageLaterality"),revised);
                }

                public void removeEmptyPatients() {
                    worklistTreeView.updateViewRemoveEmptyNode();
                }

                public void deletePhysicianList() {
                    studyPanelView.updateViewDeletePhysicianList();
                }
                public void deleteServerList() {
                    frame.updateViewDeleteServerList();
                }
            });
            controller.registerListener(new ControllerListener() {

                public void updateSelectedPatient(DB2Hash patient) {
                try {
                    patientPanelView.updatePatientData(patient);
                    //patientPanelView.updateViewAddPatient(patient);
                    //patientPanelView.updateViewAddPatient(patient.get("PatientID"),patient.get("PatientsName"),patient.get("PatientsSurName"),patient.get("PatientsBirthDate"),patient.get("PatientsSex"),patient.get("PatientComments"));
                    //patientTreeView.updatePatientData(consultation.getPatient(index));
                } catch (ParseException ex) {
                    Logger.getLogger(Application.class.getName()).log(Level.SEVERE, null, ex);
                }
                }

                public void updateSelectedStudy(DB2Hash study, DB2Hash physician) {                    
                try {
                    studyPanelView.updateStudyData(study, physician);
                    //studyPanelView.updateViewAddStudy(study);
                    //studyPanelView.updateViewAddStudy(study.get("StudyInstanceUID"),study.get("StudyName"),study.get("StudyDate"),study.get("EmmetropicMagnification_RightEye"),study.get("EmmetropicMagnification_LeftEye"),study.get("IntraOcularPressure_RightEye"),study.get("IntraOcularPressure_LeftEye"),study.get("HorizontalFieldOfView"),study.get("PupilDilated"),study.get("DegreeOfDilation_RightEye"),study.get("DegreeOfDilation_LeftEye"),study.get("SphericalLensPower_RightEye"),study.get("SphericalLensPower_LeftEye"),study.get("CylinderLensPower_RightEye"),study.get("CylinderLensPower_LeftEye"),study.get("CylinderAxis_RightEye"),study.get("CylinderAxis_LeftEye"),study.get("AxialLengthOfTheEye_RightEye"),study.get("AxialLengthOfTheEye_LeftEye"),study.get("VisualAcuityRightEyeSequence"),study.get("VisualAcuityLeftEyeSequence"),study.get("TestPatternsCodeSequence"),study.get("TestStrategyCodeSequence"),study.get("ScreeningTestModeCodeSequence"),study.get("FixationMonitoringCodeSequence"),study.get("FixationTarget"),study.get("BackgroundLuminance"),study.get("StimulusColorCodeSequence"),study.get("BackgroundIlluminationColorCodeSequence"),study.get("StimulusArea"));
                } catch (ParseException ex) {
                    Logger.getLogger(Application.class.getName()).log(Level.SEVERE, null, ex);
                }
                }

                public void updateSelectedAcquisition(DB2Hash acquisition) {
                    acquisitionPanelView.updateAcquisitionData(acquisition);
                }

                public void updateTreeSelection(String pattern) {
                    patientTreeView.updateViewSearch(pattern);
                    worklistTreeView.updateViewSearch(pattern);
                }
            });
            controller.registerAddListener(new ControllerAddListener() {

                public void updateAddPhysician(DB2Hash physician) {
                    studyPanelView.updateViewAddPhysician(physician);
                }
                public void updateAddServer(DB2Hash server) {
                    frame.updateViewAddServer(server);
                }

                public void updateEditPatient(boolean isNew, DB2Hash oldPatient, DB2Hash patient) {
                    //System.out.println("isNew: "+isNew);
                    Integer oldPatientId = null;
                    String oldPatientsName = null;
                    String oldPatientsSurName = null;
                    if (!isNew) {
                        // OldPatient data exists.
                        oldPatientId = Integer.parseInt(oldPatient.get("Id"));
                        oldPatientsName = oldPatient.get("PatientsName");
                        oldPatientsSurName = oldPatient.get("PatientsSurName");
                    }
                    patientTreeView.updateViewEditPatient(isNew, oldPatientsName, oldPatientsSurName, Integer.parseInt(patient.get("Id")), patient.get("PatientsName"), patient.get("PatientsSurName")); // Works only for PatientTree.
                    worklistTreeView.updateViewEditPatient(isNew, oldPatientsName, oldPatientsSurName, Integer.parseInt(patient.get("Id")), patient.get("PatientsName"), patient.get("PatientsSurName")); // Works only for PatientTree.
                }

                public void updateEditStudy(boolean isNew, DB2Hash patient, DB2Hash oldStudy, DB2Hash oldWorklist, DB2Hash study) {
                    /*  oldStudy: Study attributes saved on DB.
                        oldWorklist: Worklist attributes saved on DB.
                        study: Attributes inserted on StudyPanelView. 
                        
                     */
                    String oldStudyDate = null;
                    String oldWorklistDate = null;
                    if (!isNew) {   // OldStudy data exists.
                        oldStudyDate = oldStudy.get("StudyDate");                        
                        if(!oldWorklist.get("Id").isEmpty()){
                            oldWorklistDate = oldWorklist.get("ScheduledProcedureStepDateTime");
                        }
                    }
                    System.out.println("oldStudyDate: "+oldStudyDate);
                    System.out.println("oldWorklistDate: "+oldWorklistDate);
                                        
                    patientTreeView.updateViewEditStudy(isNew,  patient.get("PatientsName"), patient.get("PatientsSurName"), oldStudyDate, Integer.parseInt(study.get("Id")), study.get("StudyDate"));
                    worklistTreeView.updateViewEditStudy(isNew, patient.get("PatientsName"), patient.get("PatientsSurName"), oldWorklistDate, Integer.parseInt(study.get("Id")), study.get("StudyDate"));
                }

                public void updateEditAcquisition(boolean isNew, DB2Hash study, DB2Hash oldAcquisition, DB2Hash acquisition) {
                    //System.out.println("START CREATING VIEW CHANGES FOR ACQUISITION");
                    String oldAquisitionLaterality = null;
                    String oldAquisitionTime = null;

                    if (!isNew) { // OldAcquisition data exists.
                        oldAquisitionLaterality = oldAcquisition.get("ImageLaterality"); 
                        oldAquisitionTime = oldAcquisition.get("AcquisitionTime");
                    }   
                    
                    patientTreeView.updateViewEditAcquisition(isNew,  study.get("StudyDate"), acquisition.get("study_Id"), oldAquisitionLaterality, oldAquisitionTime, Integer.parseInt(acquisition.get("Id")), acquisition.get("ImageLaterality"), acquisition.get("AcquisitionTime"));
                }

                public void updateDeleteNode() {
                    patientTreeView.updateViewDelete();
                    patientPanelView.clearAll();
                    studyPanelView.clearAll();
                    //worklistTreeView.updateViewDeleteNode();
                }

                public void updateAddAcquisition() {
                    throw new UnsupportedOperationException("Not supported yet.");
                }

                public void checkAddHCE(int HCE_exists) {
                    patientPanelView.checkHCE(HCE_exists);
                }

                public void updateAddReferralnote(ArrayList<DB2Hash> referralNote) {
                    worklistPanelView.updateViewWorklistTable(referralNote);
                }
                public void deleteReferralnotes() {
                    worklistPanelView.clearAll();
                }
                public void previewReferralnote(DB2Hash worklist2db,DB2Hash study2db,DB2Hash patient2db) {
                    referralNotePanelView.updateReferralNotePanel(worklist2db,study2db,patient2db);
                }

                
            });

            //controller.updateWorklist(frame);   // Get the worklist from PACS.
            List<String> list = null;
            controller.loadPatientList(list,null);       // Initializes each Jtree. Doesn't need controller.
            
            //consultation.getStudyList();      // Initializes each Jtree. Doesn't need controller.
            frame.run_initComponents();         // Initializes all components on JFrame.
            controller.loadServerList();
            frame.jTabbedPane1.setEnabledAt(1, false); // Disables study tab by default.
            frame.jTabbedPane1.setEnabledAt(2, false); // Disables acquisition tab by default.
            controller.loadPhysicianList(); // Initialize performing physician's list from DB.
            setScreenSize(); // Sets the size for each Frame on the screen.
            frame.tableModel = (DefaultTableModel) frame.dcmsndTable.getModel(); // Study send table model initialization.
            frame.setDefaultCloseOperation(frame.DISPOSE_ON_CLOSE);    // Don't stop the software when close the window.            
            
            frame.addWindowListener(new WindowAdapter(){
                public void windowClosing(WindowEvent we){
                    frame.Send.setVisible(false);
                    frame.Worklist.setVisible(false);
                    frame.ReferralNote.setVisible(false);        
                }
            });
            
            frame.setVisible(true);
    }    
    
    /*public String parseDate(String dateValue){
        //System.out.println("Date value at start: "+dateValue+" length: "+dateValue.length());
        if(dateValue == null){
            dateValue = now();  // If date is unknown, assigns actual date to the study.
        }
        if(dateValue.length() > 10){
            dateValue = dateValue.substring(0, 10);
        }
        dateValue = dateValue.replaceAll("-", "/");
        //System.out.println("Parsed date value: "+dateValue);
        return dateValue;
    }*/
    public static String now() {
        Calendar cal = Calendar.getInstance();
        return tf.format(cal.getTime());
    }
    public static String dateFromNow(int days) {
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.DATE, days);
        return tf.format(cal.getTime());
    }
    
    public static String splitError(String ex) {
        String[] error = ex.toString().split(":");
        String error_txt;
        if(error.length == 1 ){error_txt = error[0];}else{error_txt = error[1];}
        return error_txt;
    }
    public void setScreenSize(){
            // Adjust Main frame's size
            screenSize = frame.getToolkit().getScreenSize();
            int screenWidth = screenSize.width;
            int screenHeight = screenSize.height-30;
            frame.setSize(screenWidth, screenHeight);
            frame.Send.setSize(screenWidth, screenHeight/2);
            frame.Worklist.setSize(screenWidth, screenHeight/2);
            frame.ReferralNote.setSize(screenWidth/2, screenHeight/2);
            frame.model = (DefaultTreeModel)frame.WorklistTree.getModel();
            frame.modelPatient = (DefaultTreeModel)frame.PatientTree.getModel();


    }
    public void show(){
        frame.setVisible(true);            
    }
    public void hide(){
        frame.setVisible(false);
    }
}
